/**
 * Created by L.jp
 * Description:给你一个链表的头节点head，请你编写代码，反复删去链表中由 总和值为 0 的连续节点组成的序列，直到不存在这样的序列为止。
 * 删除完毕后，请你返回最终结果链表的头节点。
 * 你可以返回任何满足题目要求的答案。
 * （注意，下面示例中的所有序列，都是对ListNode对象序列化的表示。）
 * 示例 1：
 * 输入：head = [1,2,-3,3,1]
 * 输出：[3,1]
 * 提示：答案 [1,2,1] 也是正确的。
 * User: 86189
 * Date: 2022-02-11
 * Time: 22:10
 */
class ListNode {
      int val;
      ListNode next;
      ListNode() {}
      ListNode(int val) { this.val = val; }
      ListNode(int val, ListNode next) { this.val = val; this.next = next; }
  }
public class Solution {
    /*   //思路：删去连续总和为0的连续节点，那么我们就要找到连续总和为0的节点，然后修改指向就可以了
                为了防止头结点也可能被删除，所以还需要借助一个虚拟头结点，最终我们返回虚拟头节点的下一个节点就可以了
                然后定义一个前驱节点pre在虚拟节点这里，pre用于外循环遍历链表
                定义一个cur节点始终在pre的后继节点，用于去判断总和是否为0，每遍历一个节点我们就用sum+cur.val
                然后判断当前sum是不是等于0，如果等于0，那么说明这些节点是要删除的，修改指向，pre.next=cur.next
                如果sum!=0,那么就说明不用删除，继续遍历下一个节点
    * */

    //简单来说就是判断从每一个节点往后到尾结点是否有连续和为0的情况，有就删除，并且重新从下一个节点开始判断，这样的话才可以彻底删除这些节点
    public ListNode removeZeroSumSublists(ListNode head) {
        //其实就是双重循环，一开始以phead为起点(外循环），（内循环）判断是否有连续和为0的连续节点(通过cur遍历，sum判断)
        ListNode phead=new ListNode(0);//借助虚拟头节点值为0
        phead.next=head;
        ListNode pre=phead;
        while(pre!=null){
            ListNode cur=pre.next;//遍历链表
            int sum=0;//连续和
            while(cur!=null){
                sum+=cur.val;
                if(sum!=0){
                    cur=cur.next;
                }else{
                    //连续和为0，那么跳过这些节点
                    pre.next = cur.next;//重新连接链表
                    break;
                }
            }
            //当cur==null时说明一轮判断连续和完成，开始下一轮
            if(cur==null){
                pre=pre.next;//前驱节点往前走，那么下一次判断的起点还是从cur=pre.next开始
            }
        }
        return phead.next;

    }
}
